import pygame
import threading
import time
from typing import Optional, Tuple, Callable

class JoystickManager:
    def __init__(self):
        self.joystick: Optional[pygame.joystick.Joystick] = None
        self.is_running = False
        self.update_thread: Optional[threading.Thread] = None
        self.callback: Optional[Callable[[float, float, float, float], None]] = None
        
        # 初始化pygame
        pygame.init()
        pygame.joystick.init()
        
        # 打印调试信息
        print(f"检测到 {pygame.joystick.get_count()} 个手柄设备")
        for i in range(pygame.joystick.get_count()):
            joy = pygame.joystick.Joystick(i)
            joy.init()
            print(f"手柄 {i}: {joy.get_name()}")
            print(f"  轴数量: {joy.get_numaxes()}")
            print(f"  按钮数量: {joy.get_numbuttons()}")
            joy.quit()
        
    def connect(self) -> bool:
        """尝试连接手柄"""
        if pygame.joystick.get_count() > 0:
            self.joystick = pygame.joystick.Joystick(0)
            self.joystick.init()
            print(f"已连接手柄: {self.joystick.get_name()}")
            print(f"轴数量: {self.joystick.get_numaxes()}")
            print(f"按钮数量: {self.joystick.get_numbuttons()}")
            return True
        print("未检测到手柄设备")
        return False
        
    def disconnect(self):
        """断开手柄连接"""
        if self.joystick:
            self.joystick.quit()
            self.joystick = None
            print("已断开手柄连接")
            
    def start_polling(self, callback: Callable[[float, float, float, float], None]):
        """开始轮询手柄状态"""
        if not self.joystick:
            print("无法开始轮询：未连接手柄")
            return False
            
        self.callback = callback
        self.is_running = True
        self.update_thread = threading.Thread(target=self._poll_loop, daemon=True)
        self.update_thread.start()
        print("开始轮询手柄数据")
        return True
        
    def stop_polling(self):
        """停止轮询手柄状态"""
        self.is_running = False
        if self.update_thread:
            self.update_thread.join()
            self.update_thread = None
            print("停止轮询手柄数据")
            
    def _poll_loop(self):
        """轮询手柄状态的循环"""
        print("进入轮询循环")
        while self.is_running:
            try:
                pygame.event.pump()  # 处理事件队列
                
                if self.joystick and self.callback:
                    # 获取左右摇杆的值
                    left_x = self.joystick.get_axis(0)  # 左摇杆X轴
                    left_y = self.joystick.get_axis(1)  # 左摇杆Y轴
                    right_x = self.joystick.get_axis(2)  # 右摇杆X轴
                    right_y = self.joystick.get_axis(3)  # 右摇杆Y轴
                    
                    # 调用回调函数
                    self.callback(left_x, left_y, right_x, right_y)
                    
            except Exception as e:
                print(f"轮询过程中发生错误: {str(e)}")
                
            time.sleep(0.016)  # 约60Hz的更新频率
            
    def cleanup(self):
        """清理资源"""
        print("开始清理手柄资源")
        self.stop_polling()
        self.disconnect()
        pygame.quit()
        print("手柄资源清理完成")
